(in-package #:geometry-object)

(defclass geo-point()
  ((point-x :initarg :point-x :accessor point-x)
   (point-y :initarg :point-y :accessor point-y)
   (point-z :initarg :point-z :accessor point-z :initform 0.0)))

(defgeneric equal? (object1 object2)
  (:documentation "Customed comparation."))
(defgeneric point-add (p1 p2))

(defmethod print-object ((object geo-point) stream)
  (format stream "#<GEO-POINT point-x: ~d, point-y: ~d, point-z: ~d>"
	  (slot-value object 'point-x) (slot-value object 'point-y) (slot-value object 'point-z)))

(defmethod equal? ((object1 t) (object2 t))
  (equal object1 object2))
(defmethod equal? ((n1 number) (n2 number))
  (= n1 n2))
(defmethod equal? ((s1 string) (s2 string))
  (string= s1 s2))
(defmethod equal? ((p1 geo-point) (p2 geo-point))
  (and (= (point-x p1) (point-x p2))
       (= (point-y p1) (point-y p2))
       (= (point-z p1) (point-z p2))))

(defmethod point-add ((point-1 geo-point) (point-2 geo-point))
  (make-instance 'geo-point
		 :point-x (+ (point-x point-1) (point-x point-2))
		 :point-y (+ (point-y point-1) (point-y point-2))
		 :point-z (+ (point-z point-1) (point-z point-2))))

(defmethod point-subtract ((point-1 geo-point) (point-2 geo-point))
  (make-instance 'geo-point
		 :point-x (- (point-x point-1) (point-x point-2))
		 :point-y (- (point-y point-1) (point-y point-2))
		 :point-z (- (point-z point-1) (point-z point-2))))

(defmethod point-scale ((point geo-point) scalar)
  (make-instance 'geo-point
		 :point-x (* (point-x point) scalar)
		 :point-y (* (point-y point) scalar)
		 :point-z (* (point-z point) scalar)))

(defmethod point-scale (scalar (point geo-point))
  (make-instance 'geo-point
		 :point-x (* (point-x point) scalar)
		 :point-y (* (point-y point) scalar)
		 :point-z (* (point-z point) scalar)))
